/*
 * Copyright (c) 2009. Silenus Consultoria, S.L.U.
 */
package es.silenus.detecta.batch.mapper;

import es.silenus.detecta.model.AnswerOrigin;
import es.silenus.detecta.model.SurveyAnswerHeaderImported;
import es.silenus.detecta.model.SurveyUnitAnswerImported;
import es.silenus.detecta.model.TrainingPreference;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;

import java.sql.Date;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Properties;
import java.util.Map;
import java.util.HashMap;


/**
 * Survey answer header imported mapper.
 *
 * @author <a href="mailto:malonso@silenus-consultoria.es">Mariano Alonso</a>
 *
 * @since 24-ago-2009 12:09:53
 */
public class SurveyAnswerHeaderImportedMapper implements FieldSetMapper<SurveyAnswerHeaderImported> {
	/**
	 * Logger for this class.
	 */
	private static final Log LOG = LogFactory.getLog(SurveyAnswerHeaderImportedMapper.class);

	/**
	 * The date format.
	 */
	private SimpleDateFormat dateFormat;

	/**
	 * The number of questions.
	 */
	private int questions;

	/**
	 * Internet map.
	 */
	private Map<String, Integer> internetMap;

	/**
	 * Constructor.
	 */
	public SurveyAnswerHeaderImportedMapper() {
		dateFormat = new SimpleDateFormat("ddMMyy");
		questions = 16;

		internetMap = new HashMap<String, Integer>();
		internetMap.put("Y", 1);
		internetMap.put("S", 1);
		internetMap.put("N", 0);
	}

	/**
	 * Sets the date format.
	 *
	 * @param format the date format.
	 */
	public void setDateFormat(final String format) {
		this.dateFormat = new SimpleDateFormat(format);
	}

	/**
	 * Sets the number of questions.
	 *
	 * @param questions the number of questions.
	 */
	public void setQuestions(int questions) {
		this.questions = questions;
	}

	private Integer parseInternet(final String internet) {
		Integer value = null;

		if(internet != null) {
			value = internetMap.get(internet.toUpperCase());
		}

		if(value == null) {
			LOG.warn(String.format("Unknown value %s for internet field", internet));
			value = 0;
		}

		return value;
	}

	/**
	 * Method used to map data obtained from a {@link FieldSet} into an object.
	 *
	 * @param fieldSet the {@link FieldSet} to map
	 *
	 * @return the mapped element.
	 */
	public SurveyAnswerHeaderImported mapFieldSet(final FieldSet fieldSet) {
		if(fieldSet == null) {
			return null;
		}

		final Properties properties = fieldSet.getProperties();

		String id = properties.getProperty("id");

		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("Processing record: %s", id));
		}

		// Basic attributes
		SurveyAnswerHeaderImported result = new SurveyAnswerHeaderImported();

		result.setOrigin(AnswerOrigin.LOAD);

		String temp;

		// Header attributes
		temp = properties.getProperty("surveyCode");
		if(temp.length() > 20) {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("Record: %s has too long survey code: %s", id, temp));
			}
			return null;
		}
		result.setSurveyCode(temp.trim());

		temp = properties.getProperty("actionCode");
		if(temp.length() > 20) {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("Record: %s has too long action code: %s", id, temp));
			}
			return null;
		}
		result.setActionCode(temp.trim());

		temp = properties.getProperty("councilId");
		if(temp.length() > 20) {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("Record: %s has too long council id: %s", id, temp));
			}
			return null;
		}
		result.setCouncilId(temp.trim());

		temp = properties.getProperty("entityId");
		if(temp.length() > 20) {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("Record: %s has too long entity id: %s", id, temp));
			}
			return null;
		}
		result.setEntityId(temp.trim());


		try {
			result.setCreationDate(new Date(dateFormat.parse(properties.getProperty("surveyDate")).getTime()));
		} catch(ParseException e) {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("Record: %s has wrong survey date", id), e);
			}
		}

		result.setInternetConnection(parseInternet(properties.getProperty("internet").trim()));


		// Process unit answers
		String q;
		String question;
		String mode;
		SurveyUnitAnswerImported unitAnswer;
		TrainingPreference preference;

		for(int i = 0; i < questions; ++i) {
			q = String.valueOf(i + 1);
			question = properties.getProperty("q" + q);
			mode = properties.getProperty("m" + q);

			if(question != null && question.length() <= 20) {
				unitAnswer = new SurveyUnitAnswerImported();
				unitAnswer.setQuestionNumber(i + 1);
				unitAnswer.setQuestionCode(question.trim());

				if(mode != null) {
					try {
						preference = TrainingPreference.getById(Integer.parseInt(mode.trim()));
					} catch(NumberFormatException e) {
						if(LOG.isDebugEnabled()) {
							LOG.debug(String.format("Record: %s has wrong preference for question %s", id, q), e);
						}

						preference = TrainingPreference.PRESENTIAL;
					}

					if(preference == null) {
						preference = TrainingPreference.PRESENTIAL;
					}

					unitAnswer.setPreference(preference);
				}

				result.add(unitAnswer);
			} else {
				if(LOG.isDebugEnabled()) {
					LOG.debug(String.format("Record: %s has wrong question code for question %s=%s", id, q, question));
				}
			}
		}


		return result;
	}
}
